package com.byx.chatclient.adapter;

import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.Environment;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.byx.chatclient.R;
import com.byx.chatclient.entity.Constant;
import com.byx.chatclient.entity.message.AudioMsgBody;
import com.byx.chatclient.entity.message.FileMsgBody;
import com.byx.chatclient.entity.message.ImageMsgBody;
import com.byx.chatclient.entity.message.Message;
import com.byx.chatclient.entity.message.MsgSendStatus;
import com.byx.chatclient.entity.message.MsgType;
import com.byx.chatclient.entity.message.TextMsgBody;
import com.byx.chatclient.entity.message.VideoMsgBody;
import com.byx.chatclient.utils.FileUtils;
import com.byx.chatclient.utils.GlideUtils;
import com.byx.chatclient.utils.GsonUtil;
import com.byx.chatclient.utils.ThreadPoolUtil;
import com.byx.chatclient.utils.TimeFormatUtil;
import com.byx.chatclient.widget.BubbleImageView;
import com.chad.library.adapter.base.BaseDelegateMultiAdapter;
import com.chad.library.adapter.base.delegate.BaseMultiTypeDelegate;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.HashMap;
import java.util.List;

/**
 * @author Superb
 * 聊天消息适配器
 */
public class ChatAdapter extends BaseDelegateMultiAdapter<Message,BaseViewHolder> {
    private Context mContext;
    private String mSenderId;
    private boolean mIsSingleChat;

    /**
     * 最长消息发送时间间隔，超过将显示发送时间
     */
    private static final long MAX_MESSAGE_TIME_STEP_TIP= 5 * 60;

    private static final int TYPE_SEND_TEXT=1;
    private static final int TYPE_RECEIVE_TEXT=2;
    private static final int TYPE_SEND_IMAGE=3;
    private static final int TYPE_RECEIVE_IMAGE=4;
    private static final int TYPE_SEND_VIDEO=5;
    private static final int TYPE_RECEIVE_VIDEO=6;
    private static final int TYPE_SEND_FILE=7;
    private static final int TYPE_RECEIVE_FILE=8;
    private static final int TYPE_SEND_AUDIO=9;
    private static final int TYPE_RECEIVE_AUDIO=10;

    private static final int SEND_TEXT = R.layout.item_text_send;
    private static final int RECEIVE_TEXT = R.layout.item_text_receive;
    private static final int SEND_IMAGE = R.layout.item_image_send;
    private static final int RECEIVE_IMAGE = R.layout.item_image_receive;
    private static final int SEND_VIDEO = R.layout.item_video_send;
    private static final int RECEIVE_VIDEO = R.layout.item_video_receive;
    private static final int SEND_FILE = R.layout.item_file_send;
    private static final int RECEIVE_FILE = R.layout.item_file_receive;
    private static final int RECEIVE_AUDIO = R.layout.item_audio_receive;
    private static final int SEND_AUDIO = R.layout.item_audio_send;
    /*
    private static final int SEND_LOCATION = R.layout.item_location_send;
    private static final int RECEIVE_LOCATION = R.layout.item_location_receive;*/

    public ChatAdapter(Context context, String senderId, boolean isSingleChat) {
        super();
        this.mContext = context;
        this.mSenderId = senderId;
        this.mIsSingleChat = isSingleChat;
        init();

    }

    public ChatAdapter(Context context, @Nullable List<Message> data, String senderId, boolean isSingleChat) {
        super(data);
        mContext = context;
        mSenderId = senderId;
        mIsSingleChat = isSingleChat;
        init();
    }

    private void init() {
        BaseMultiTypeDelegate<Message> multiTypeDelegate = new BaseMultiTypeDelegate<Message>() {
            @Override
            public int getItemType(@NotNull List<? extends Message> list, int i) {

                Message message = list.get(i);
                boolean isSend = message.getSenderId().equals(mSenderId);
                if (MsgType.TEXT==message.getMsgType()) {
                    return isSend ? TYPE_SEND_TEXT : TYPE_RECEIVE_TEXT;
                }else if(MsgType.IMAGE==message.getMsgType()){
                    return isSend ? TYPE_SEND_IMAGE : TYPE_RECEIVE_IMAGE;
                }else if(MsgType.VIDEO==message.getMsgType()){
                    return isSend ? TYPE_SEND_VIDEO : TYPE_RECEIVE_VIDEO;
                }else if(MsgType.FILE==message.getMsgType()){
                    return isSend ? TYPE_SEND_FILE : TYPE_RECEIVE_FILE;
                }else if(MsgType.AUDIO==message.getMsgType()){
                    return isSend ? TYPE_SEND_AUDIO : TYPE_RECEIVE_AUDIO;
                }
                return 0;
            }
        };
        multiTypeDelegate.addItemType(TYPE_SEND_TEXT,SEND_TEXT)
                .addItemType(TYPE_RECEIVE_TEXT,RECEIVE_TEXT)
                .addItemType(TYPE_SEND_IMAGE,SEND_IMAGE)
                .addItemType(TYPE_RECEIVE_IMAGE,RECEIVE_IMAGE)
                .addItemType(TYPE_SEND_FILE,SEND_FILE)
                .addItemType(TYPE_RECEIVE_FILE,RECEIVE_FILE)
                .addItemType(TYPE_SEND_VIDEO,SEND_VIDEO)
                .addItemType(TYPE_RECEIVE_VIDEO,RECEIVE_VIDEO)
                .addItemType(TYPE_SEND_AUDIO,SEND_AUDIO)
                .addItemType(TYPE_RECEIVE_AUDIO,RECEIVE_AUDIO);
        setMultiTypeDelegate(multiTypeDelegate);

        addChildClickViewIds(R.id.rlAudio);
        addChildClickViewIds(R.id.bivPic);
        addChildClickViewIds(R.id.rc_msg_canceled);
    }

    @Override
    protected void convert(@NotNull BaseViewHolder baseViewHolder, Message message) {
        setContent(baseViewHolder,message);
        if (message.getSenderId().equals(mSenderId)){
            setStatus(baseViewHolder,message,message.getMsgType().equals(MsgType.IMAGE));
        }
    }

    @Override
    public void onBindViewHolder(@NotNull BaseViewHolder holder, int position) {
        //自定义发送时间显示
        TextView tvSendTime = holder.findView(R.id.tv_send_message_time);
        assert tvSendTime != null;
        long sendTime = getItem(position).getSentTime();
        if(position == 0 || TimeFormatUtil.timeOver(getItem(position-1).getSentTime(),sendTime,MAX_MESSAGE_TIME_STEP_TIP)){
            tvSendTime.setVisibility(View.VISIBLE);
            tvSendTime.setText(TimeFormatUtil.format(sendTime));
        }else {
            tvSendTime.setVisibility(View.GONE);
        }

        super.onBindViewHolder(holder, position);
    }

    private void setStatus(BaseViewHolder helper, Message item,boolean isImage) {
        //只需要设置自己发送的状态
        MsgSendStatus sentStatus = item.getSentStatus();
        if (sentStatus == MsgSendStatus.SENDING) {
            helper.setVisible(R.id.chat_item_progress, !isImage).setVisible(R.id.chat_item_fail, false);
        } else if (sentStatus == MsgSendStatus.FAILED) {
            helper.setVisible(R.id.chat_item_progress, false).setVisible(R.id.chat_item_fail, true);
        } else if (sentStatus == MsgSendStatus.SENT) {
            helper.setVisible(R.id.chat_item_progress, false).setVisible(R.id.chat_item_fail, false);
        }
    }

    private void setContent(BaseViewHolder helper, Message item) {
        switch (item.getMsgType()){
            case TEXT:
                TextMsgBody msgBody1 = (TextMsgBody) item.getBody();
                helper.setText(R.id.chat_item_content_text, msgBody1.getMessage());
                break;
            case IMAGE:
                ImageMsgBody msgBody2 = (ImageMsgBody) item.getBody();
                if (TextUtils.isEmpty(msgBody2.getThumbUrl())) {
                    GlideUtils.loadImage(mContext, msgBody2.getRemoteUrl(), helper.getView(R.id.bivPic));
                } else {
                    File file = new File(msgBody2.getThumbUrl());
                    if (file.exists()) {
                        GlideUtils.loadImage(mContext, msgBody2.getThumbUrl(), helper.getView(R.id.bivPic));
                    } else {
                        GlideUtils.loadImage(mContext, msgBody2.getRemoteUrl(), helper.getView(R.id.bivPic));
                    }
                }
                break;
            case VIDEO:
                VideoMsgBody msgBody3 = (VideoMsgBody) item.getBody();
                MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
                if (FileUtils.isFileExists(msgBody3.getLocalPath())) {
                    //生成缩略图路径
                    mediaMetadataRetriever.setDataSource(msgBody3.getLocalPath());
                    Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime();
                    ((BubbleImageView) helper.getView(R.id.bivPic)).setImageBitmap(bitmap);
                }else {
                    ThreadPoolUtil.runInBackground(() -> {
                        mediaMetadataRetriever.setDataSource(msgBody3.getRemoteUrl(), new HashMap<>());
                        Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime();
                        ThreadPoolUtil.runOnMainThread(() -> ((BubbleImageView)helper.getView(R.id.bivPic)).setImageBitmap(bitmap));
                    });
                }
                break;
            case FILE:
                FileMsgBody msgBody4 = (FileMsgBody) item.getBody();
                helper.setText(R.id.msg_tv_file_name, msgBody4.getDisplayName());
                helper.setText(R.id.msg_tv_file_size, msgBody4.getSize() + "B");
                if (FileUtils.isFileExists(msgBody4.getLocalPath())){
                    helper.setText(R.id.rc_msg_canceled,"打开");
                }else {
                    helper.setText(R.id.rc_msg_canceled,"下载");
                }
                break;
            case AUDIO:
                AudioMsgBody msgBody5 = (AudioMsgBody) item.getBody();
                helper.setText(R.id.tvDuration, msgBody5.getDuration() + "\"");
                break;
            default:break;
        }

        TextView tvGroupNickName = helper.findView(R.id.tv_group_nick_name);
        assert tvGroupNickName != null;
        System.out.println(item.getBody().getExtra());
        JsonObject extraObject = JsonParser.parseString(item.getBody().getExtra()).getAsJsonObject();
        if (mIsSingleChat){
            tvGroupNickName.setVisibility(View.GONE);
        }else {
            if (item.getBody().getExtra() != null){
                if (extraObject.has(Constant.JSON_KEY_SENDER_NICK_NAME)){
                    tvGroupNickName.setText(extraObject.get(Constant.JSON_KEY_SENDER_NICK_NAME).getAsString());
                }
            }
        }
        if (extraObject.has(Constant.JSON_KEY_SENDER_AVATAR)){
            GlideUtils.loadImage(mContext,extraObject.get(Constant.JSON_KEY_SENDER_AVATAR).getAsString(),helper.getView(R.id.chat_item_header));
        }
    }
}
